/*
 * Controller test class
 * Authors: Daniel Henderson
 * TCSS 360 (Group project) Spring 2013 
 * University of Washington
 */
package JUnitTests;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import org.junit.Before;
import org.junit.Test;

import Model.Conference;
import Model.Controller;
import Model.Deadline;
import Model.Paper;
import Model.User;

/**
 * Primary JUNIT test class that will test the various functionality
 * of the controller methods.
 * 
 * @author Daniel Henderson
 * @version 1.0
 */
public class ControllerTests {

	private User james;	
	private User jill;	
	private User judy;	
	private User jake;
	private User janas;
	private User jimmy;
	private User jeremy;
	private Controller controller;
	private Paper paper;
	private Conference conf;
	private Deadline deadline;
	
	/**
	 * Construct List of Conferences and Users to test.
	 * 
	 * @throws java.lang.Exception
	 */
	@Before
	public void setUp() throws Exception {
		
		//create new Controller
		controller = new Controller();
		
		//PC Chair conf
		james = new User("james1", "password", "james@yahoo.com", "james");	
		
		//Author of paper
		jill = new User("jill1", "password", "jill@yahoo.com", "jill");		
		
		//Reviewer of paper
		judy = new User("judy1", "password", "judy@yahoo.com", "judy");	
		
		//SPC of paper
		jake = new User("jake1", "password", "jake@yahoo.com", "jake");	
		
		
		janas = new User("janas1", "password", "janas@yahoo.com", "janas");		
		jimmy = new User("jimmy1", "password", "jimmy@yahoo.com", "jimmy");
		jeremy = new User("jeremy1", "password", "jeremy@yahoo.com", "jeremy");
		
		//Add Users to Userlist
		//THIS SHOWS THET ADDUSETOSYSTEM WORKS
		controller.addUserToSystem(james);
		controller.addUserToSystem(jill);
		controller.addUserToSystem(judy);
		controller.addUserToSystem(jake);
		controller.addUserToSystem(janas);
		controller.addUserToSystem(jimmy);
		controller.addUserToSystem(jeremy);
		
		deadline = new Deadline(12, 12, 12);
		conf = new Conference("The Conference", james, deadline, deadline, deadline, deadline, deadline);
		paper = new Paper("c:\text.txt", "conf_cat", "This Paper", "The Keywords", "The Abstract Descr", conf, jill);
		
	}
	
	/**
	 * Test method that will test the setCurrentUser and getCurrentUser methods.
	 * A user is set to current user, then we check that the getcurrent
	 * user method pulls this specific user.
	 */
	@Test
	public void testCurrentUser() {
		assertTrue(controller.setCurrentUser("james1", "password"));
		assertTrue("james1".contentEquals(controller.getCurrentUser().getLogin()));
		assertFalse(controller.setCurrentUser("jill1", "pass"));
	}
	
	/**
	 * Test method that will test the getUserList method.
	 * Make sure list is not empty, not null, and >= 0
	 */
	@Test
	public void testGetUserList() {
		assertTrue(!controller.getUserList().isEmpty());
		assertFalse(controller.getUserList().size() >= 0 && controller.getUserList() == null);
	}
	
	/**
	 * Test method that will test the getAdminUser method.
	 * Make sure the admin account matches the seeded default 
	 * credentials that the User is not null.
	 * 
	 */
	@Test
	public void testGetAdminUser() {
		assertTrue(controller.getAdminUser().getLogin().contentEquals("admin"));
		assertTrue(controller.getAdminUser().getPassword().contentEquals("password"));
		assertFalse(controller.getAdminUser() == null);
	}
	
	/**
	 * Test method that will test the approveRejectPaper method.
	 * We set whether to accept or reject these two papers,
	 * then test the getAcceptedStatus method to be sure it matches.
	 */
	@Test
	public void testApproveRejectPaper() {
		controller.approveRejectPaper(1, paper);
		assertTrue(paper.getAcceptedStatus() == 1);	
		controller.approveRejectPaper(2, paper);
		assertTrue(paper.getAcceptedStatus() == 2);
	}
	
	/**
	 * Test method that will test the assignReviewer method.
	 * Assign a review, then test that the getReviewers method pulls
	 * the correct user. Also test the getpermissions method and 
	 * be sure that was set properly when user became a reviewer. Lastly,
	 * test that the review paper matches.
	 */
	@Test
	public void testAssignReviewer() {
		controller.assignReviewer(paper, judy);
		assertTrue(paper.getReviewers().get(0).getLogin().contentEquals(judy.getLogin()));	
		assertTrue(judy.getPermissions()[1]);
		assertTrue(judy.getReviewPapers().get(0).getUniqueCode() == paper.getUniqueCode());
	}
	
	/**
	 * Test method that will test the assignSPC method.
	 * Assign the user to SPC status. CHeck to be sure the method set 
	 * the user, check that User permissions are set properly, and
	 * check that the Paper matches.
	 */
	@Test
	public void testAssignSPC() {
		controller.assignSPC(paper, jake);
		assertTrue(paper.getSPC().getLogin().contentEquals(jake.getLogin()));	
		assertTrue(jake.getPermissions()[2]);
		assertTrue(jake.getSPCPapers().get(0).getUniqueCode() == paper.getUniqueCode());
	}
	
	/**
	 * Test method that will test the assignSPC method.
	 * Set the current user, try changing the users settings
	 * with data that should not work. Then Try once with data
	 * that should work. Then check that the information changed successfully.
	 */
	@Test
	public void testChangeUserSettings() {
		assertTrue(controller.setCurrentUser("jill1", "password"));
		assertFalse(controller.changeUserSettings("jill1", "123", "123@123.com", "")); //empty password check
		assertFalse(controller.changeUserSettings("jill1", "123", "123123.com", "password")); //improper email check
		assertFalse(controller.changeUserSettings("jill1", "123", "", "password")); //empty email check
		assertFalse(controller.changeUserSettings("jill1", "", "123123.com", "password")); //empty name check
		assertTrue(controller.changeUserSettings("jill1", "123", "123@123.com", "password")); //This should work
		assertTrue(jill.getLogin().contentEquals("jill1"));
		jill = controller.getCurrentUser();

		assertTrue(jill.getfullname().contentEquals("123"));
		assertTrue(jill.getEmail().contentEquals("123@123.com"));
		assertTrue(jill.getPassword().contentEquals("password"));
	}

	/**
	 * Test method that will test the uniqueUsername method.
	 * Method will send names in to be sure the system will either
	 * accept them or reject them. THe first one should work because
	 * this user does not exist already. The last two should be false
	 * because both should already exist.
	 */
	@Test
	public void testuniqueUsername () {
		assertTrue(controller.uniqueUsername("OMGOMGOMG"));	
		assertFalse(controller.uniqueUsername("jill1"));
		assertFalse(controller.uniqueUsername("admin"));
	}
	
	/**
	 * Test method that will test the uniqueCOnferenceNamae method
	 * and also the addConferenceToSystemMethod. Add conference to
	 * system, check for unique names. Then check list not empty
	 * and not null.
	 */
	@Test
	public void testuniqueConferenceName () {
		controller.addConferenceToSystem(conf);
		assertTrue(controller.uniqueConferenceName("OMGOMGOMG"));	
		assertFalse(controller.uniqueConferenceName("The Conference"));
		assertTrue(!controller.getConferenceList().isEmpty() && controller.getConferenceList() != null); 
	}
	
	/**
	 * Test method that will test the deletePaper method. Set the current user
	 * of the system. Not try to delete the paper from system. Be sure that
	 * the getPCPapers method returns the proper value which should be 0.
	 * Then check to be sure the paper was removed from the other lists
	 * of the conference.
	 */
	@Test
	public void testdeletePaper() {
		assertTrue(controller.setCurrentUser("jill1", "password"));
		controller.deletePaper(paper);
		
		assertTrue(controller.getPCPapers().size() == 0);
		assertTrue(paper.getConference().getConferencePapers().size() == 0);
		assertTrue(paper.getConference().getProgramChair().getPCPapers().size() == 0);
	}
	
	
	/**
	 * Test method that will test the modifyRecommendation() method.
	 * Set the recommendation and rationale, then get those values back from the
	 * controller and be sure they match what was sent in.
	 */
	@Test
	public void testmodifyRecommendation() {
		controller.modifyRecommendation(paper, 5, "The Rationale");		
		assertTrue(paper.getRecommendation() == 5);
		assertTrue(paper.getRationale().contentEquals("The Rationale"));
	}
	
	/**
	 * Test method that will test the modifyRecommendation() method.
	 * Send in the values for a review along with the reviewer and the paper,
	 * than get the review back from the paper and be sure this matches.
	 */
	@Test
	public void testreviewPaper() {
		controller.reviewPaper(paper, 1, 1, 1, 1, 5, 5, 5, 5, 9, 9, "The paper is great", judy);		
		assertTrue(paper.getReview(0).getComments().contentEquals("The paper is great"));
		assertTrue(paper.getReview(0).getReviewer().getLogin().contentEquals(judy.getLogin()));
	}
	
	/**
	 * Test method that will test the modifyRecommendation() method.
	 * Submit a paper to the system. THen run the the Author Papers
	 * list to see if it was added to the system properly. The papers
	 * unique ID will be compared inside the Author Papers list and also
	 * inside the Conference Paper list.
	 */
	@Test
	public void testsubmitPaper() {
		assertTrue(controller.setCurrentUser("jill1", "password"));
		controller.submitPaper(paper, conf);		
		boolean doesExistConf = false;
		boolean doesExistAuthor = false;
		for(Paper thepaper : controller.getCurrentUser().getAuthorPapers()) {
			if(thepaper.getUniqueCode() == paper.getUniqueCode()) {
				doesExistAuthor = true;
			}
		}
		assertTrue(doesExistAuthor);
		
		for(Paper thepaper : paper.getConference().getConferencePapers()) {
			if(thepaper.getUniqueCode() == paper.getUniqueCode()) {
				doesExistConf = true;
			}
		}
		assertTrue(doesExistConf);
	}

}
